package refresh

import (
	"encoding/json"
	"gin/app/http/global"
	"gin/app/http/model/product"
	"gin/app/http/response"
	"github.com/elastic/go-elasticsearch/v8"
	"github.com/elastic/go-elasticsearch/v8/esapi"
	"github.com/gin-gonic/gin"
	"strings"
)

// 刷新产品es缓存
func ProductEs(c *gin.Context) {
	productId := c.DefaultQuery("id", "")
	var arr product.Product
	var DB = global.DB
	var es = global.Es
	result := DB.Where("id = ?", productId).First(&arr)
	if result.RowsAffected != 0 {
		jsonData, err := json.Marshal(arr)
		if err != nil {
			response.Fail(c, "刷新缓存失败", gin.H{"error": err})
			return
		}
		req := esapi.IndexRequest{
			Index:      global.ProductIndex,
			DocumentID: productId, // 文档ID
			Body:       strings.NewReader(string(jsonData)),
		}
		res, err := req.Do(c, es)
		if err != nil {
			response.Fail(c, "刷新缓存失败", gin.H{"error": err})
			return
		}
		if res.IsError() {
			response.Fail(c, "刷新缓存失败", gin.H{"error": res.String()})
			return
		}
		response.Success(c, "刷新缓存成功", gin.H{})
	} else {
		req := esapi.DeleteRequest{
			Index:      global.ProductIndex,
			DocumentID: productId, // 文档ID
		}
		res, err := req.Do(c, es)
		if err != nil {
			response.Fail(c, "刷新缓存失败", gin.H{"error": err})
			return
		}
		if res.StatusCode != 200 && res.StatusCode != 404 {
			response.Fail(c, "刷新缓存失败", gin.H{"error": res.String()})
			return
		}
		response.Success(c, "刷新缓存成功", gin.H{})
	}

}

// 刷新所有产品es缓存
func ProductEsAll(c *gin.Context) {
	var arr []product.Product
	var DB = global.DB
	var es = global.Es
	RebuildIndex(c, es) //重剪索引
	result := DB.Find(&arr)
	if result.RowsAffected != 0 {
		for _, v := range arr {
			// 构建文档数据
			doc := map[string]interface{}{
				"id":             v.Id,
				"name":           v.Name,
				"price":          v.Price,
				"stock_quantity": v.Stock_quantity,
				"image":          v.Image,
				"category_id":    v.Category_id,
				"created_at":     v.Created_at.Format("2006-01-02 15:04:05"), // 时间转换为字符串
				"updated_at":     v.Updated_at.Format("2006-01-02 15:04:05"), // 时间转换为字符串
			}
			jsonData, err := json.Marshal(doc)
			if err != nil {
				response.Fail(c, "刷新缓存失败", gin.H{"error": err})
				return
			}
			req := esapi.IndexRequest{
				Index: global.ProductIndex,
				Body:  strings.NewReader(string(jsonData)),
			}
			res, err := req.Do(c, es)
			if err != nil {
				response.Fail(c, "刷新缓存失败", gin.H{"error": err})
				return
			}
			if res.IsError() {
				response.Fail(c, "刷新缓存失败", gin.H{"error": res.String()})
				return
			}
		}
		response.Success(c, "刷新缓存成功", gin.H{})
	}
}

func RebuildIndex(c *gin.Context, es *elasticsearch.Client) {
	//删除索引
	req := esapi.IndicesDeleteRequest{
		Index: []string{global.ProductIndex},
	}
	res, err := req.Do(c, es)
	if err != nil {
		response.Fail(c, "删除索引失败", gin.H{"error": err})
		return
	}
	if res.StatusCode != 200 && res.StatusCode != 404 {
		response.Fail(c, "删除索引失败", gin.H{"error": res.String()})
		return
	}

	//新建索引
	req2 := esapi.IndicesCreateRequest{
		Index: global.ProductIndex,
		Body: strings.NewReader(`{
        "settings": {
            "number_of_shards": 5,
            "number_of_replicas": 0
        },
        "mappings": {
            "properties": {
                "id": {
                    "type": "integer"
                },
                "name": {
                    "type": "text",
                    "analyzer": "ik_max_word"
                },
                "price": {
                    "type": "float"
                },
                "stock_quantity": {
                    "type": "integer"
                },
                "image": {
                    "type": "keyword"
                },
                "category_id": {
                    "type": "integer"
                },
                "category_name": {
                    "type": "keyword"
                },
                "created_at": {
                    "type": "date",
                    "format": "yyyy-MM-dd HH:mm:ss"
                },
                "updated_at": {
                    "type": "date",
                    "format": "yyyy-MM-dd HH:mm:ss"
                }
            }
        }
    }`),
	}

	res2, err := req2.Do(c, es)
	if err != nil {
		response.Fail(c, "创建索引失败", gin.H{"error": err})
		return
	}
	if res2.StatusCode != 200 && res2.StatusCode != 404 {
		response.Fail(c, "创建索引失败", gin.H{"error": res2.String()})
		return
	}

}
